﻿#region usings

using System;
using System.Diagnostics;

#endregion

namespace Mp3Observer.Common
{
    /// <summary>
    /// Inheriting from this class provides thread safe Singleton pattern with double lock check
    /// </summary>
    /// <example>
    /// <code>
    /// <![CDATA[public class Workspace : Singleton<Workspace> { ...]]>
    /// </code>
    /// </example>
    /// <typeparam name="T">any object that has a public ctor</typeparam>
    [DebuggerStepThrough]
    public abstract class Singleton<T> where T : new()
    {
        #region Fields

        /// <summary>
        /// a flag to check is the current thread online?
        /// </summary>
        [ThreadStatic]
        private static int syncFlag = 0;

        /// <summary>
        /// the object for the lock
        /// </summary>
        private static object syncRoot = new object();

        /// <summary>
        /// the instance of the singleton object
        /// </summary>
        private static T instance;

        #endregion

        #region Properties

        /// <summary>
        /// Gets the Instance and creates the object on the first read attempt
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes", Justification = "ok so")]
        public static T Instance
        {
            get
            {
                // is the current thread online?
                if (syncFlag == 0)
                {
                    lock (syncRoot)
                    {
                        if (instance == null)
                            instance = new T();
                    }

                    // indicate the current thread is online
                    syncFlag = 1;
                }
                return instance;
            }
        }

        /// <summary>
        /// Creates this instance.
        /// </summary>
        public void Create()
        {
        }

        #endregion
    }
}
